/*
 * Android Runner is a multiplayer GPS game fully written by "Xurxo Mendez Perez"
 * 
 * Copyright (C) 2009 "Xurxo Mendez Perez"
 *   
 * This file is part of Android Runner.
 * 
 * Android Runner is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Android Runner is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Android Runner.  If not, see <http://www.gnu.org/licenses/>.
 */

package es.sonxurxo.androidrunner.view.web.application;

import org.apache.wicket.Application;
import org.apache.wicket.Request;
import org.apache.wicket.Response;
import org.apache.wicket.Session;
import org.apache.wicket.authentication.AuthenticatedWebApplication;
import org.apache.wicket.authentication.AuthenticatedWebSession;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.protocol.http.WebRequestCycleProcessor;
import org.apache.wicket.protocol.http.request.CryptedUrlWebRequestCodingStrategy;
import org.apache.wicket.protocol.http.request.WebRequestCodingStrategy;
import org.apache.wicket.request.IRequestCodingStrategy;
import org.apache.wicket.request.IRequestCycleProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import es.sonxurxo.androidrunner.model.service.game.GameService;
import es.sonxurxo.androidrunner.model.service.player.PlayerService;
import es.sonxurxo.androidrunner.view.web.pages.game.create.CreateGamePage;
import es.sonxurxo.androidrunner.view.web.pages.game.editor.GameEditorPage;
import es.sonxurxo.androidrunner.view.web.pages.game.find.details.finished.FinishedGameDetailsPage;
import es.sonxurxo.androidrunner.view.web.pages.game.find.details.notfinished.GameDetailsPage;
import es.sonxurxo.androidrunner.view.web.pages.game.find.list.finished.FinishedGamesListPage;
import es.sonxurxo.androidrunner.view.web.pages.game.find.list.notfinished.ActiveGamesListPage;
import es.sonxurxo.androidrunner.view.web.pages.game.find.list.notfinished.NotFinishedGamesListPage;
import es.sonxurxo.androidrunner.view.web.pages.game.live.WatchGamePage;
import es.sonxurxo.androidrunner.view.web.pages.home.admin.AdminHomePage;
import es.sonxurxo.androidrunner.view.web.pages.home.anonymous.AnonymousHomePage;
import es.sonxurxo.androidrunner.view.web.pages.home.player.PlayerHomePage;
import es.sonxurxo.androidrunner.view.web.pages.question.CreateQuestionPage;
import es.sonxurxo.androidrunner.view.web.pages.user.login.LoginPage;
import es.sonxurxo.androidrunner.view.web.pages.user.register.RegisterPage;
import es.sonxurxo.androidrunner.view.web.session.AndroidRunnerSession;
import es.sonxurxo.androidrunner.view.web.ws.game.AbandonGameWS;
import es.sonxurxo.androidrunner.view.web.ws.game.AnswerQuestionWS;
import es.sonxurxo.androidrunner.view.web.ws.game.FindCitiesWithGamesWS;
import es.sonxurxo.androidrunner.view.web.ws.game.FindGameByIdWS;
import es.sonxurxo.androidrunner.view.web.ws.game.FindGamesByCityWS;
import es.sonxurxo.androidrunner.view.web.ws.game.FindGamesByLocationWS;
import es.sonxurxo.androidrunner.view.web.ws.game.GetItemWS;
import es.sonxurxo.androidrunner.view.web.ws.game.JoinGameWS;
import es.sonxurxo.androidrunner.view.web.ws.game.SendMessageWS;
import es.sonxurxo.androidrunner.view.web.ws.game.StartOrContinueGameWS;
import es.sonxurxo.androidrunner.view.web.ws.game.UpdateLocationWS;
import es.sonxurxo.androidrunner.view.web.ws.game.WatchGameWS;
import es.sonxurxo.androidrunner.view.web.ws.player.ChangePasswordWS;
import es.sonxurxo.androidrunner.view.web.ws.player.GetHistoryOfGamesWS;
import es.sonxurxo.androidrunner.view.web.ws.player.GetPublicPlayerProfileWS;
import es.sonxurxo.androidrunner.view.web.ws.player.LoginWS;
import es.sonxurxo.androidrunner.view.web.ws.player.LogoutWS;
import es.sonxurxo.androidrunner.view.web.ws.player.RegisterWS;
import es.sonxurxo.androidrunner.view.web.ws.player.UpdatePersonalInfoWS;

/**
 * @author "Xurxo Mendez Perez"
 *
 */
@Component
public class AndroidRunnerApplication extends AuthenticatedWebApplication {

	@Autowired
	private GameService gameService;
	
	@Autowired
	private PlayerService playerService;
	
	public AndroidRunnerApplication() {
		super();
	}
	
	/* (non-Javadoc)
     * @see org.apache.wicket.authentication.AuthenticatedWebApplication#init()
     */
	@Override
    protected void init() {
        super.init();
        
        mountBookmarkablePage("/main", AnonymousHomePage.class);
        mountBookmarkablePage("/admin/home", AdminHomePage.class);
        mountBookmarkablePage("/player/home", PlayerHomePage.class);
        mountBookmarkablePage("/gameDetails", GameDetailsPage.class);
        mountBookmarkablePage("/finishedGameDetails", FinishedGameDetailsPage.class);
        mountBookmarkablePage("/edit", GameEditorPage.class);
        mountBookmarkablePage("/create", CreateGamePage.class);
        mountBookmarkablePage("/watchGame", WatchGamePage.class);
        mountBookmarkablePage("/loginPage", LoginPage.class);
        mountBookmarkablePage("/registerPage", RegisterPage.class);
        mountBookmarkablePage("/addQuestion", CreateQuestionPage.class);
        mountBookmarkablePage("/activeGames", ActiveGamesListPage.class);
        mountBookmarkablePage("/notFinishedGames", NotFinishedGamesListPage.class);
        mountBookmarkablePage("/finishedGames", FinishedGamesListPage.class);
        
        mountBookmarkablePage("/changePassword", ChangePasswordWS.class);
        mountBookmarkablePage("/getHistoryOfGames", GetHistoryOfGamesWS.class);
        mountBookmarkablePage("/getPublicPlayerProfile", GetPublicPlayerProfileWS.class);
        mountBookmarkablePage("/login", LoginWS.class);
        mountBookmarkablePage("/logout", LogoutWS.class);
        mountBookmarkablePage("/register", RegisterWS.class);
        mountBookmarkablePage("/updatePersonalInfo", UpdatePersonalInfoWS.class);
        mountBookmarkablePage("/abandonGame", AbandonGameWS.class);
        mountBookmarkablePage("/answerQuestion", AnswerQuestionWS.class);
        mountBookmarkablePage("/findCitiesWithGames", FindCitiesWithGamesWS.class);
        mountBookmarkablePage("/findGameById", FindGameByIdWS.class);
        mountBookmarkablePage("/findGamesByCity", FindGamesByCityWS.class);
        mountBookmarkablePage("/findGamesByLocation", FindGamesByLocationWS.class);
        mountBookmarkablePage("/getItem", GetItemWS.class);
        mountBookmarkablePage("/joinGame", JoinGameWS.class);
        mountBookmarkablePage("/sendMessage", SendMessageWS.class);
        mountBookmarkablePage("/startOrContinueGame", StartOrContinueGameWS.class);
        mountBookmarkablePage("/updateLocation", UpdateLocationWS.class);
        mountBookmarkablePage("/watchGameWS", WatchGameWS.class);
        
        getApplicationSettings().setAccessDeniedPage(LoginPage.class);

        /*
         * Remove wicket tags from result HTML
         */
        getMarkupSettings().setStripWicketTags(true);
    }

	@Override
	public Class<? extends WebPage> getHomePage() {
		AndroidRunnerSession session = AndroidRunnerSession.get();
		if (session.isSignedIn() && !session.isSessionInvalidated()) {
			for (String role : session.getRoles()) {
				if (role.equals("ADMIN")) {
					return AdminHomePage.class;
				}
				if (role.equals("PLAYER")) {
					return PlayerHomePage.class;
				}
			}
		}
		return AnonymousHomePage.class;
	}

	@Override
	public Session newSession(Request request, Response response) {
	
		return new AndroidRunnerSession(request);
	}
	
	@Override
	protected IRequestCycleProcessor newRequestCycleProcessor() {

		return new WebRequestCycleProcessor() {
			@Override
			protected IRequestCodingStrategy newRequestCodingStrategy() {
				return new CryptedUrlWebRequestCodingStrategy(new WebRequestCodingStrategy());
			}
		};
	}  
	
	public static AndroidRunnerApplication get() {
        return (AndroidRunnerApplication) Application.get();
    }
	
	public GameService getGameService() {
		return this.gameService;
	}
	
	public PlayerService getPlayerService() {
		return this.playerService;
	}

	@Override
	protected Class<? extends WebPage> getSignInPageClass() {
		return AnonymousHomePage.class;
	}

	@Override
	protected Class<? extends AuthenticatedWebSession> getWebSessionClass() {
		return AndroidRunnerSession.class;
	}
}
